package com.my.lucky.service;

import com.my.lucky.model.ExRightDividend;
import com.my.lucky.model.Stock;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 股票复权计算服务
 */
public class StockAdjustmentService {

    /**
     * 计算前复权价格
     *
     * @param stocks           待计算的股票数据列表（按日期正序排列）
     * @param exRightDividends 除权除息数据列表（按日期正序排列）
     * @return 计算后的股票数据列表
     */
    public List<Stock> calculateForwardAdjustment(List<Stock> stocks, List<ExRightDividend> exRightDividends) {
        if (stocks == null || stocks.isEmpty()) {
            return Collections.emptyList();
        }

        // 按股票代码分组除权除息数据
        Map<String, List<ExRightDividend>> exRightMap = exRightDividends.stream()
                .collect(Collectors.groupingBy(ExRightDividend::getCode));

        // 按股票代码分组处理
        Map<String, List<Stock>> stockMap = stocks.stream()
                .collect(Collectors.groupingBy(Stock::getCode));

        List<Stock> result = new ArrayList<>();

        // 对每个股票代码进行处理
        for (String code : stockMap.keySet()) {
            List<Stock> stockList = stockMap.get(code);
            List<ExRightDividend> exRightList = exRightMap.getOrDefault(code, Collections.emptyList());

            // 计算该股票的前复权数据
            result.addAll(calculateSingleStockAdjustment(stockList, exRightList));
        }

        return result;
    }

    /**
     * 计算单个股票的前复权价格
     */
    private List<Stock> calculateSingleStockAdjustment(List<Stock> stocks, List<ExRightDividend> exRightDividends) {
        if (exRightDividends.isEmpty()) {
            return stocks; // 没有除权除息数据，直接返回原始数据
        }

        double cumulativeFactor = 1.0;
        int exRightIndex = 0;
        ExRightDividend currentExRight = exRightDividends.get(exRightIndex);

        for (Stock stock : stocks) {
            // 检查是否需要更新复权因子
            while (exRightIndex < exRightDividends.size() &&
                    stock.getDate().compareTo(currentExRight.getDate()) >= 0) {
                // 计算新的复权因子
                double factor = calculateFactor(currentExRight);
                cumulativeFactor *= factor;

                // 移动到下一个除权除息点
                exRightIndex++;
                if (exRightIndex < exRightDividends.size()) {
                    currentExRight = exRightDividends.get(exRightIndex);
                } else {
                    break;
                }
            }

            // 设置累积复权因子
            stock.setAdjustmentFactor(cumulativeFactor);
        }

        return stocks;
    }

    /**
     * 计算单个除权除息事件的复权因子
     */
    private double calculateFactor(ExRightDividend exRight) {
        double beforePrice = exRight.getBeforePrice();
        double afterPrice = exRight.getAfterPrice();
        double dividend = exRight.getDividend();
        double transfer = exRight.getTransfer();
        double allotment = exRight.getAllotment();
        double allotmentPrice = exRight.getAllotmentPrice();

        // 考虑转增、送股、配股和现金分红的复权因子计算
        double denominator = beforePrice;
        double numerator = afterPrice * (1 + transfer + allotment) - allotment * allotmentPrice - dividend;

        return denominator / numerator;
    }

    /**
     * 获取前复权后的股票数据
     *
     * @param stock 原始股票数据
     * @return 复权后的新股票对象
     */
    public Stock getAdjustedStock(Stock stock) {
        return new Stock(
                stock.getCode(),
                stock.getDate(),
                stock.getForwardAdjustedClose(),
                stock.getForwardAdjustedOpen(),
                stock.getForwardAdjustedHigh(),
                stock.getForwardAdjustedLow(),
                stock.getVolume()
        );
    }
} 